package com.example.jetour_line.map.mapview;

import android.content.Context;
import android.content.res.Resources;
import android.location.Location;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptor;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.RouteSearch.DriveRouteQuery;
import com.amap.api.services.route.WalkRouteResult;
import com.example.jetour_line.R;
import com.example.jetour_line.map.mapview.overlay.DrivingRouteOverlay;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BaseMapView extends FrameLayout implements LifeListenerFragment.LifeListener {// implements AMap.InfoWindowAdapter
    private TextureMapView mapView;
    private AMap aMap;
    private MarkerClickListener markerClickListener;//marker点击事件
    private RouteSearch routeSearch;//驾车出行路线规划
    private RouteSearch newRouteSearch;//驾车出行路线规划
    private DrivingRouteOverlay drivingRouteOverlay;//线路绘制
    private DrivingRouteOverlay lineOverlay;//折现绘制

    private DrivingRouteOverlay newDrivingRouteOverlay;//线路绘制
    private DrivingRouteOverlay newLineOverlay;//折现绘制
    private String driveColor = "#CE4A58";//自定义路线颜色
    private String newDriveColor = "#CE4A58";//自定义路线颜色
    private Marker selMarker = null; //选中的marker
    private Map<String,Marker> allMarkers = new HashMap<>();//所以marker集合
    private boolean isShowRight = false;
    private boolean canDrawLine = true;//是否可以绘制线路到地图上  （有些页面绘制数据出来的时候 返回了 地图还在 不能绘制）
    private CountDownTimer countDownTimer;

    public void setCanDrawLine(boolean canDrawLine) {
        this.canDrawLine = canDrawLine;
    }

    UserMoveMapListener userMoveMapListener;

    public void setUserMoveMapListener(UserMoveMapListener userMoveMapListener) {
        this.userMoveMapListener = userMoveMapListener;
    }

    public void setShowRight(boolean showRight) {
        isShowRight = showRight;
    }

    //自定义路线颜色
    public void setDriveColor(String driveColor) {
        this.driveColor = driveColor;
    }
    //自定义路线颜色
    public void setNewDriveColor(String newDriveColor) {
        this.newDriveColor = newDriveColor;
    }
    private boolean isUserMove = false;//是否被用户主动移动地图

    public boolean isUserMove() {
        return isUserMove;
    }

    public void setUserMove(boolean userMove) {
        isUserMove = userMove;
    }

    Context mContext;

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        LifeListenerManager.addLifeListener(getContext(), this,"BaseMapView");
    }

    //marker点击事件回调
    public void setMarkerClickListener(MarkerClickListener markerClickListener) {
        this.markerClickListener = markerClickListener;
    }
    public BaseMapView(Context context ) {
        super(context);
        View view = LayoutInflater.from(context).inflate(R.layout.gao_map_view,
                this);
        mContext = context;
        mapView = findViewById(R.id.gao_map_view);
        aMap =  mapView.getMap();

        UiSettings mUiSettings = aMap.getUiSettings();
        mUiSettings.setTiltGesturesEnabled(false);// 禁用倾斜手势。
        mUiSettings.setRotateGesturesEnabled(false);// 禁用旋转手势
        mUiSettings.setZoomControlsEnabled(false);
        aMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_MOVE:
                        //滑动
                        isUserMove = true;
                        // 倒计时
                        if (countDownTimer!=null){
                            countDownTimer.cancel();
                            countDownTimer = null;
                        }else{}
                        initCountDown();
                        break;
                    case MotionEvent.ACTION_UP:
                        if(userMoveMapListener != null){
                            userMoveMapListener.onUp();
                        }
                        //抬起
                        break;
                    case MotionEvent.ACTION_DOWN: //按下
                        if(userMoveMapListener != null){
                            userMoveMapListener.onDown();
                        }
                        break;
                    default:
                        break;
                }
            }
        });
        // 绑定 Marker 被点击事件
        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                BaseMarkerModel model = (BaseMarkerModel) marker.getObject();
//                Log.d("SDKonMarkerClick",model.getMarkerView().canSel+"");
                if(markerClickListener != null){
                    markerClickListener.onMarkerClick(model);
//                    Log.d("SDKonMarkerClick",model.getMarkerView().canSel+"111");
                }
                if(model.getMarkerView().canSel){//
//                    Log.d("SDKonMarkerClick",model.getMarkerView().canSel+"2222");
                    changeSelMarkerView(model);
                }
                return true;
            }
        });


    }

    private void initCountDown() {
        countDownTimer = new CountDownTimer(10*1000,1000){

             @Override
             public void onTick(long millisUntilFinished) {

             }

             @Override
             public void onFinish() {
                 isUserMove = false;
                 countDownTimer.cancel();
                 countDownTimer = null;
             }
         };
        countDownTimer.start();
    }

    /**
     * 设置是否可以拖动地图 默认true 可以
     */
    public void setCanScroll(boolean canScroll){
        UiSettings mUiSettings = aMap.getUiSettings();
        mUiSettings.setScrollGesturesEnabled(canScroll);
    }
    /**
     * 定位蓝标
     */
    public void initLocatingPoint(BitmapDescriptor myLocationIcon) {
            MyLocationStyle myLocationStyle;
            myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点，定位点依照设备方向旋转，并且会跟随设备移动。（1秒1次定位）如果不设置myLocationType，默认也会执行此种模式。
            myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
            myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
            myLocationStyle.myLocationIcon(myLocationIcon);
            myLocationStyle.strokeWidth(1f);
            myLocationStyle.strokeColor(R.color.black);
            myLocationStyle.radiusFillColor(R.color.dwlb_tc);
            aMap.setMyLocationStyle(myLocationStyle);
            aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点，false表示隐藏定位蓝点
            aMap.addOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
                @Override
                public void onMyLocationChange(Location location) {
                    changeMapCenter(new BaseLatLonPoint(location.getLatitude(),location.getLongitude()));
                }
            });

    }

    /**
     *  改变地图中心点
     * */
    public void changeMapCenter(BaseLatLonPoint point){
        if(isUserMove == false){
            float zoom = aMap.getCameraPosition().zoom;//目标可视区域的缩放级别 zoom
            float tilt = aMap.getCameraPosition().tilt;//目标可视区域的倾斜度，以角度为单位。tilt
            float bearing = aMap.getCameraPosition().bearing;//可视区域指向的方向，以角度为单位，从正北向顺时针方向计算，从0度到360度  bearing

            CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                    new LatLng(point.getLatitude(),point.getLongitude()),zoom,tilt,bearing));
            aMap.animateCamera(mCameraUpdate);
        }
    }
    /**
     *  改变地图缩放级别
     * */
    public void changeMapZoom(float zoom){
        float tilt = aMap.getCameraPosition().tilt;//目标可视区域的倾斜度，以角度为单位。tilt
        float bearing = aMap.getCameraPosition().bearing;//可视区域指向的方向，以角度为单位，从正北向顺时针方向计算，从0度到360度  bearing
        CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                aMap.getCameraPosition().target,zoom,tilt,bearing));
        aMap.animateCamera(mCameraUpdate);
    }
    /**
     *  改变地图Bound  左 右 上 下 的边距
     * */
    public void changeMapBound(List<BaseMarkerModel> gaoMarkerModels,int left, int right ,int top ,int bottom){
        LatLngBounds.Builder b = b = LatLngBounds.builder();
        for (int i = 0; i < gaoMarkerModels.size(); i++) {
            b.include(new LatLng(gaoMarkerModels.get(i).getPoint().getLatitude(), gaoMarkerModels.get(i).getPoint().getLongitude()));
        }
        int screenWidth =  Resources.getSystem().getDisplayMetrics().widthPixels;//屏幕宽度
        aMap.animateCamera(CameraUpdateFactory
                .newLatLngBoundsRect(b.build(), left,right,top,bottom));//left right top bottom
    }


    /**
     *  将地图中心点 移动到屏幕上的某个点
     * */
    public void setPointToCenter(int x,int y){
        aMap.setPointToCenter(x,y);
    }

    /** 后续 应将带有网络图片的 markerview封装进来
     * 添加markerView 是否先清除地图
     * */

    public void addMarkerOptions(List<BaseMarkerModel> gaoMarkerModels ,boolean clear){
        ArrayList<MarkerOptions> allMarkerOptions = new ArrayList<>();
        if(clear){
            allMarkers.clear();
        }
        LatLngBounds.Builder b = b = LatLngBounds.builder();
        for (int i = 0; i < gaoMarkerModels.size(); i++) {
            MarkerOptions markerOptions = getMarkerOption(gaoMarkerModels.get(i));
            allMarkerOptions.add(markerOptions);
            b.include(new LatLng(gaoMarkerModels.get(i).getPoint().getLatitude(), gaoMarkerModels.get(i).getPoint().getLongitude()));
        }
        //在地图上添一组图片标记（marker）对象，并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示。

        ArrayList<Marker> markers =  aMap.addMarkers(allMarkerOptions,false);
        for (int i = 0; i < markers.size(); i++) {
            BaseMarkerModel model = gaoMarkerModels.get(i);
            Marker marker = markers.get(i);
            marker.setObject(model);
            if(model.getMarkerView().isSelect && selMarker == null){
                selMarker = marker;
            }
            allMarkers.put(gaoMarkerModels.get(i).getId(),marker);
        }

        int screenWidth = isShowRight? Resources.getSystem().getDisplayMetrics().widthPixels:50;//屏幕宽度
        aMap.animateCamera(CameraUpdateFactory
                .newLatLngBoundsRect(b.build(), screenWidth/2,80,50,10));//left right top bottom
    }


    /** 后续 应将带有网络图片的 markerview封装进来
     * 添加markerView
     * */
    public void addMarkerOptions(List<BaseMarkerModel> gaoMarkerModels){
        addMarkerOptions(gaoMarkerModels,true);
    }
    /**
     * 添加单个markerView
    * */
    public void addMarkerOption(BaseMarkerModel gaoMarkerModel){
        Marker marker = aMap.addMarker(getMarkerOption(gaoMarkerModel));
        marker.setObject(gaoMarkerModel);
        allMarkers.put(gaoMarkerModel.getId(),marker);
    }

    /**
     * 改变markerView经纬度
     * */
    public void changeMarkerViewLocation(BaseMarkerModel gaoMarkerModel){
        Marker marker = allMarkers.get(gaoMarkerModel.getId());
        if(marker != null){
            marker.setPosition(new LatLng(gaoMarkerModel.getPoint().getLatitude(),gaoMarkerModel.getPoint().getLongitude()));
        }
    }

    /**
     * 改变markerView经纬度
     * */
    public void changeMarkerViewLocationByID(String id,double lat,double lng){
        Marker marker = allMarkers.get(id);
        if(marker != null){
            marker.setPosition(new LatLng(lat,lng));
        }
    }

    /**
     * 获取markerView
     * */
    private MarkerOptions getMarkerOption(BaseMarkerModel gaoMarkerModel){
        MarkerOptions markerOption = new MarkerOptions();
        markerOption.position(new LatLng(gaoMarkerModel.getPoint().getLatitude(),gaoMarkerModel.getPoint().getLongitude()));
//        markerOption.title("北京").snippet("北京市：34.341568, 108.940174");
//        markerOption.draggable(true);//设置Marker可拖动
        markerOption.icon(BitmapDescriptorFactory.fromView(gaoMarkerModel.getMarkerView()));
        // 将Marker设置为贴地显示，可以双指下拉地图查看效果
        markerOption.setFlat(false);//设置marker平贴地图效果
        return markerOption;
    }
    /**
     * 通过ID改变markerView选中状态
     * */
    public void changeSelMarkerView(String id){
        Marker marker = allMarkers.get(id);
        BaseMarkerModel markerModel = (BaseMarkerModel) marker.getObject();
        changeSelMarkerView(markerModel);
    }
    /**
     * 通过ID删除marker
     */
    public void removeMarkerView(String id){
        Marker marker = allMarkers.get(id);
        marker.remove();
        allMarkers.remove(id);
    }

    /**
     * 改变markerView选中状态
     * */
    public void changeSelMarkerView(BaseMarkerModel gaoMarkerModel){
        Marker marker = allMarkers.get(gaoMarkerModel.getId());
        if(marker == null){
            return;
        }
        if(selMarker != null){//将上一次选中的marker 设置为未选中状态
            BaseMarkerModel model = (BaseMarkerModel) selMarker.getObject();
            if(model.getId().equals(gaoMarkerModel.getId())){//需要改变的marker 已经是选中状态
                return;
            }
            BaseMarkerView oldView = model.getMarkerView().getNewMarker(false);
            selMarker.setIcon(BitmapDescriptorFactory.fromView(oldView));
            model.setMarkerView(oldView);
            selMarker.setObject(model);
            selMarker.setZIndex(0);
//            selMarker.setPosition();//改变坐标经纬度
        }

        BaseMarkerView selView = gaoMarkerModel.getMarkerView().getNewMarker(true);
        marker.setIcon(BitmapDescriptorFactory.fromView(selView));
        gaoMarkerModel.setMarkerView(selView);
        marker.setObject(gaoMarkerModel);
        marker.setZIndex(2);
        selMarker = marker;
    }



    /**
     * 清理地图上的所有覆盖物
     * */
    public void clearMap(){
        aMap.clear();//
        aMap.setMyLocationEnabled(false);
        selMarker = null;
        allMarkers.clear();
        drivingRouteOverlay = null;
        lineOverlay = null;
        newDrivingRouteOverlay = null;
        newLineOverlay = null;
    }

    /**
     * 线路规划绘制 规划失败后 绘制折线
     * */
    public void routePlanning(List<BaseMarkerModel> points){
        if(points == null || points.size() <=1){
            return;
        }
        planningLine(points,false);
    }
    /**
     * 线路规划绘制 规划失败后 绘制折线 (另外绘制一条其他颜色的)
     * */
    public void newRoutePlanning(List<BaseMarkerModel> points){
        planningLine(points,true);
    }

    private void planningLine(List<BaseMarkerModel> points,boolean isNew){
        RouteSearch search ;
        if(isNew){
            search = newRouteSearch;
        }else{
            search = routeSearch;
        }
        if(search == null){
            try {
                search = new RouteSearch(mContext);
                search.setRouteSearchListener(new RouteSearch.OnRouteSearchListener() {
                    @Override
                    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

                    }
                    @Override
                    public void onDriveRouteSearched(DriveRouteResult result, int errorCode) {
//                        Log.d("onDriveRouteSearched",errorCode+"onDriveRouteSearched");
                        if(!canDrawLine){
                            return;
                        }
                        if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
                            if (result != null && result.getPaths() != null) {
                                if (result.getPaths().size() > 0) {

                                    final DrivePath drivePath = result.getPaths()
                                            .get(0);
                                    if(drivePath == null) {
                                        return;
                                    }

                                    DrivingRouteOverlay routeOverlay;
                                    if(isNew){
                                        routeOverlay = newDrivingRouteOverlay;
                                        if(newLineOverlay != null){
                                            newLineOverlay.removeFromMap();
                                        }
                                    }else{
                                        routeOverlay = drivingRouteOverlay;
                                        if(lineOverlay != null){
                                            lineOverlay.removeFromMap();
                                        }
                                    }

                                    if(routeOverlay == null){
                                        routeOverlay = new DrivingRouteOverlay(
                                                mContext, aMap, drivePath,
                                                result.getStartPos(),
                                                result.getTargetPos(), null);
                                    }
                                    routeOverlay.setDriveColor(isNew ?newDriveColor: driveColor);//自定义路线颜色。
                                    routeOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
                                    routeOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况，默认true
                                    routeOverlay.removeFromMap();

                                    routeOverlay.addToMap();
//                                    drivingRouteOverlay.zoomToSpan();
                                    int dis = (int) drivePath.getDistance();
                                    int dur = (int) drivePath.getDuration();

                                } else if (result != null && result.getPaths() == null) {
                                    //对不起，没有搜索到相关数据
                                    if(isNew){
                                        newAddLineOverlay(points);
                                    }else{
                                        addLineOverlay(points);
                                    }

                                }

                            } else {
                                //对不起，没有搜索到相关数据
                                if(isNew){
                                    newAddLineOverlay(points);
                                }else{
                                    addLineOverlay(points);
                                }
                            }
                        } else {
                            //
                            if(isNew){
                                newAddLineOverlay(points);
                            }else{
                                addLineOverlay(points);
                            }
                        }

                    }

                    @Override
                    public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

                    }

                    @Override
                    public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

                    }
                });
            }  catch (Exception e) {
                e.printStackTrace();
            }
        }

        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(
                points.get(0).getPoint(), points.get(points.size()-1).getPoint());
        List<LatLonPoint> passedByPoints = new ArrayList<>();//途经点
        for (int i = 0; i < points.size(); i++) {
            if(i != 0 && i != points.size()-1){
                passedByPoints.add(points.get(i).getPoint());
            }
        }
//        Log.d("passedByPoints",passedByPoints.toString());
        DriveRouteQuery query = new DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, passedByPoints,
                null, "");// 第一个参数表示路径规划的起点和终点，第二个参数表示驾车模式，第三个参数表示途经点，第四个参数表示避让区域，第五个参数表示避让道路
//        Log.d("passedByPointsquery",query.toString());
        search.calculateDriveRouteAsyn(query);// 异步路径规划驾车模式查询
    }


    /**
     *  绘制折线
     * */
    public void addLineOverlay(List<BaseMarkerModel> points){
        lineOverlayPlan(points,false);
    }

    public void newAddLineOverlay(List<BaseMarkerModel> points){
        lineOverlayPlan(points,true);
    }

    private void lineOverlayPlan(List<BaseMarkerModel> points ,boolean isNew){
        DrivingRouteOverlay overlay ;
//        Log.d("lineOverlayPlan","lineOverlayPlanStart");
        if(isNew){
            overlay = newLineOverlay;
            if(newDrivingRouteOverlay != null){
                newDrivingRouteOverlay.removeFromMap();
            }
        }else{
            overlay = lineOverlay;
            if(drivingRouteOverlay != null){
                drivingRouteOverlay.removeFromMap();
            }
        }
        if(overlay == null){
            overlay = new DrivingRouteOverlay(
                    mContext, aMap,  points);
        }
        overlay.setDriveColor(isNew ?newDriveColor: driveColor);//自定义路线颜色。
        overlay.removeFromMap();
        overlay.addLine();
        Log.d("lineOverlayPlan","lineOverlayPlanEnd");
         //   lineOverlay.zoomToSpan();
//        Log.d("lineOverlayPlan","lineOverlayPlanEnd");
//                lineOverlay.zoomToSpan();
    }




//window
//    @Override
//    public View getInfoWindow(Marker marker) {
//        View infoContent = getLayoutInflater().inflate(
//                R.layout.custom_info_contents, null);
//        render(marker, infoContent);
//        return infoContent;
//    }
//
//    @Override
//    public View getInfoContents(Marker marker) {
//        return null;
//    }


    @Override
    public void onCreate(Bundle bundle) {
        mapView.onCreate(bundle);
    }

    @Override
    public void onStart() {

    }

    @Override
    public void onResume() {
        //在activity执行onResume时执行mMapView.onResume ()，重新绘制加载地图
        mapView.onResume();
    }

    @Override
    public void onPause() {
        //在activity执行onPause时执行mMapView.onPause ()，暂停地图的绘制
        mapView.onPause();
    }

    @Override
    public void onStop() {

    }

    @Override
    public void onDestroy() {
        //在activity执行onDestroy时执行mMapView.onDestroy()，销毁地图
        mapView.onDestroy();

        if (countDownTimer != null) {
            countDownTimer.cancel();
            countDownTimer = null;
        }

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        mapView.onSaveInstanceState(outState);
    }


    public interface MarkerClickListener {
        void onMarkerClick(BaseMarkerModel model);
    }

    public interface UserMoveMapListener {
        void onDown();
        void onUp();
    }
}
